#include "TcpClient.h"
#include "FloraLogger.h"
TcpClient::TcpClient(QObject *parent) : QTcpSocket(parent),
    m_reconnectInterval(m_initialReconnectInterval)
{
    connect(this, &QTcpSocket::readyRead, this, &TcpClient::onReadyRead);
    //1connect(this, &QTcpSocket::errorOccurred, this, &TcpClient::onError);
    connect(this, &QTcpSocket::disconnected, this, &TcpClient::onDisconnected);
    connect(this, &QTcpSocket::connected, this, &TcpClient::connected);

    connect(&m_reconnectTimer, &QTimer::timeout, this, &TcpClient::reconnect);
    connect(&m_connectTimeoutTimer, &QTimer::timeout, this, &TcpClient::onConnectTimeout);

    m_reconnectTimer.setInterval(m_initialReconnectInterval);
    m_connectTimeoutTimer.setSingleShot(true);
}

TcpClient::~TcpClient()
{
}

void TcpClient::connectToServer(const QString &host, quint16 port)
{
    m_host = host;
    m_port = port;
    m_reconnectInterval = m_initialReconnectInterval;  // Reset reconnect interval
    QTcpSocket::connectToHost(host, port);
    m_connectTimeoutTimer.start(10000);  // Set connection timeout to 10 seconds
}

void TcpClient::sendData(const QByteArray &data)
{
    if (state() == QTcpSocket::ConnectedState)
    {
        write(data);
    }
}

void TcpClient::onReadyRead()
{
    QByteArray data = readAll();
    emit dataReceived(data);
    LOG_DEBUG<<"tcp recive:"<<data;
}

void TcpClient::onError(QAbstractSocket::SocketError error)
{
    emit errorOccurred(errorString());
}

void TcpClient::onDisconnected()
{
    emit disconnected();
    m_reconnectTimer.start();  // Start the reconnect timer when disconnected
}

void TcpClient::reconnect()
{
    if (state() == QTcpSocket::UnconnectedState)
    {
        QTcpSocket::connectToHost(m_host, m_port);
        m_connectTimeoutTimer.start(10000);  // Set connection timeout to 10 seconds
        m_reconnectInterval = qMin(m_reconnectInterval * 2, m_maxReconnectInterval);  // Exponential backoff
    }
}

void TcpClient::onConnectTimeout()
{
    if (state() == QTcpSocket::ConnectingState)
    {
        // Connection attempt timed out
        emit connectionFailed("Connection attempt timed out.");
        disconnectFromHost();
    }
}
